package com.ygl.sba;

import com.alibaba.fastjson.JSONObject;
import de.codecentric.boot.admin.server.cloud.discovery.InstanceDiscoveryListener;
import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.values.InstanceId;
import de.codecentric.boot.admin.server.services.InstanceRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

/**
 * @Author yanggld
 * @Date 2020/1/14-21:34
 * @Description
 */
@Slf4j
@Component
public class MyInstanceDiscoveryListener extends InstanceDiscoveryListener {

	private HashMap<String,ServiceInstance> instanceMap = new HashMap<>();
	private DiscoveryClient discoveryClient;
	private InstanceRegistry registry;
	private InstanceRepository repository;

	private static final String SOURCE = "discovery";

	DingtalkNotifier dingtalkNotifier = new DingtalkNotifier();


	public MyInstanceDiscoveryListener(DiscoveryClient discoveryClient, InstanceRegistry registry, InstanceRepository repository) {
		super(discoveryClient, registry, repository);
		this.discoveryClient = discoveryClient;
		this.registry = registry;
		this.repository = repository;
	}

	/**
	 * 与nacos保持30秒的心跳
	 * @param instance
	 * @return
	 */
	@Override
	protected Mono<InstanceId> registerInstance(ServiceInstance instance) {
		log.debug("与注册中心之间的心跳----------");
		Mono<InstanceId> instanceIdMono = super.registerInstance(instance);
		instanceIdMono.subscribe(instanceId -> {
			String instanceIdValue = instanceId.getValue();
			if (!instanceMap.containsKey(instanceIdValue)) {
				instanceMap.put(instanceIdValue,instance);
				log.info("Registering discovered instanceId = {}, instance {}",instanceIdValue,JSONObject.toJSON(instance));
				log.info("**************************************************************");
				log.info("****************************{}**********************************","服务注册通知");
				try {
					dingtalkNotifier.sendMsg(NotificationType.UP,instance);
				} catch (Exception e) {
					e.printStackTrace();
				}
				log.info("**************************************************************");
			}
		});
		return instanceIdMono;
	}

	@Override
	protected Mono<Void> removeStaleInstances(Set<InstanceId> registeredInstanceIds) {
		return repository.findAll()
				.filter(Instance::isRegistered)
				.filter(instance -> SOURCE.equals(instance.getRegistration().getSource()))
				.map(Instance::getId)
				.filter(id -> !registeredInstanceIds.contains(id))
				.doOnNext((instanceId) -> {
					String instanceIdValue = instanceId.getValue();
					if (instanceMap.containsKey(instanceIdValue)) {
						ServiceInstance instance = instanceMap.get(instanceIdValue);
						instanceMap.remove(instanceIdValue);
						try {
							dingtalkNotifier.sendMsg(NotificationType.DOWN,instance);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					log.info("Instance '{}' missing in DiscoveryClient services and will be removed.", instanceIdValue);
					log.info("**************************************************************");
					log.info("****************************{}**********************************","服务下线通知");
					log.info("**************************************************************");
				})
				.flatMap(registry::deregister)
				.then();
	}
}
